package com.tempjob.admin.controller;

import com.tempjob.admin.security.annotation.AdminLogAnnotation;
import com.tempjob.admin.security.annotation.AdminLogIgore;
import com.tempjob.admin.security.annotation.AdminPassportSSO;
import com.tempjob.common.businesss.mongo.entity.SysPermission;
import com.tempjob.common.businesss.mongo.entity.SysRole;
import com.tempjob.common.businesss.mongo.entity.SysAdmin;
import com.tempjob.common.businesss.mongo.entity.SysAdminRole;
import com.tempjob.common.businesss.mongo.service.SysAdminRoleService;
import com.tempjob.common.businesss.mongo.service.SysAdminService;
import com.tempjob.common.businesss.service.MongoBeanUtil;
import com.tempjob.common.businesss.service.UserPermissionService;
import com.tempjob.common.businesss.service.UserSessionService;
import com.tempjob.common.context.AdminContextManage;
import com.tempjob.common.context.AdminContext;
import com.tempjob.common.dto.admin.*;
import com.tempjob.common.exception.BusinessException;
import com.tempjob.common.utils.CachedBeanCopier;
import com.tempjob.common.utils.CheckPasswordMeterUtils;
import com.tempjob.common.utils.PasswordUtils;
import com.tempjob.common.vo.admin.SysUserInfoVO;
import com.tempjob.common.vo.admin.UserRoleOperationReqVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 用户管理
 *
 * @version V1.0
 */
@RestController
@Api(tags = "用户管理", value = "用户管理")
@RequestMapping("/sys/user")
@Slf4j
@AdminPassportSSO
@CrossOrigin(originPatterns = "*", methods = {RequestMethod.GET, RequestMethod.POST})
public class UserController {

    @Autowired
    private UserPermissionService userPermissionService;

    @Autowired
    private MongoBeanUtil mongoBeanUtil;

    @Autowired
    private SysAdminService userService;

    @Autowired
    private UserSessionService userSessionService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @PostMapping(value = "/login")
    @ApiOperation(value = "用户登录接口")
    @AdminPassportSSO(ignore = true)
    @AdminLogAnnotation(title = "用户管理", action = "用户登录")
    public Object login(@RequestBody LoginDTO dto, HttpServletRequest httpServletRequest) {
        //校验图像验证码
//        validImageCode(dto.getCaptcha());
        return userPermissionService.login(dto, httpServletRequest);
    }

    @PostMapping(value = "/restpwd")
    @AdminPassportSSO(ignore = true)
    public Object restpwd(@RequestBody ResetPwdDTO dto) {
        //校验图像验证码
        validImageCode(dto.getCaptcha());
        SysAdmin sysAdmin = userService.one(userService.lambdaQuery().eq(SysAdmin::getUsername, dto.getUsername()));
        if (null == sysAdmin) {
            throw new BusinessException("用户名或密码错误");
        }
        if (sysAdmin.getStatus() == 2) {
            throw new BusinessException("用户名或密码错误");
        }
        if (!PasswordUtils.matches(sysAdmin.getSalt(), dto.getOldPassword(), sysAdmin.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }
        if (!CheckPasswordMeterUtils.CheckPswMeter(dto.getPassword())) {
            throw new BusinessException("密码强度不足!");
        }
        sysAdmin.setPassword(PasswordUtils.encode(dto.getPassword(), sysAdmin.getSalt()));
        return userService.updateById(sysAdmin);
    }

    @PostMapping("/update")
    @ApiOperation(value = "更新用户信息接口")
    @AdminLogAnnotation(title = "用户管理", action = "更新用户信息")
    public Object updateUserInfo(@RequestBody ModifySysUserDTO dto) {
        if (dto.getId() == null) {
            userPermissionService.addUser(dto);
            return true;
        }
        userPermissionService.updateUserInfo(dto);
        return true;
    }

    @PostMapping("/updateSelf")
    @ApiOperation(value = "更新自己信息接口")
    @AdminLogAnnotation(title = "用户管理", action = "更新用户信息")
    public Object updateUserInfoById(@RequestBody ModifyUserMyDTO dto) {
        return userPermissionService.updateUserInfoMy(dto);
    }

    @PostMapping("/{id}")
    @ApiOperation(value = "查询用户详情接口")
    @AdminLogAnnotation(title = "用户管理", action = "查询用户详情")
    public Object detailInfo(@PathVariable("id") Long id) {
        return userService.getById(id);
    }

    @GetMapping("/detail")
    @ApiOperation(value = "查询用户详情接口", response = SysUserInfoVO.class)
//    @LogAnnotation(title = "用户管理", action = "查询用户详情")
    @AdminLogIgore
    public Object detail() {
        AdminContext adminInfo = AdminContextManage.getContext();
        SysAdmin userInfo = userService.lambdaQuery().eq(SysAdmin::getId, adminInfo.getId()).one();
        SysUserInfoVO vo = new SysUserInfoVO();
        CachedBeanCopier.copyObject(userInfo, vo);
        List<SysRole> userRoles = userPermissionService.getRoleByUserid(adminInfo.getId());
        vo.setRoles(userRoles);
        List<SysPermission> permissions = userPermissionService.getPermission(adminInfo.getId());
        Set<String> perms = new HashSet<>();
        for (SysPermission sysPermission : permissions) {
            if (sysPermission.getPerms() != null && !StringUtils.isEmpty(sysPermission.getPerms())) {
                Set<String> perm = new HashSet<>(Arrays.asList(sysPermission.getPerms().split(",")));
                perms.addAll(perm);
            }
        }
        vo.setPermissionNodes(userPermissionService.permissionTreeList(adminInfo.getId()));
        vo.setPerms(perms);
        return vo;
    }

    @PostMapping("/list")
    @ApiOperation(value = "分页获取用户列表接口")
    @AdminLogIgore
//    @LogAnnotation(title = "用户管理", action = "分页获取用户列表")
    public Object pageInfo(@RequestBody QueryUserDTO dto) {
        return userPermissionService.pageInfo(dto);
    }

    @PostMapping("/logout")
    @ApiOperation(value = "退出接口")
    @AdminLogAnnotation(title = "用户管理", action = "退出")
    public Object logout() {
        userSessionService.logout(AdminContextManage.getAuthorization());
        return true;
    }

    @PostMapping("/pwd")
    @ApiOperation(value = "修改密码接口")
    @AdminLogAnnotation(title = "用户管理", action = "更新密码")
    public Object updatePwd(@RequestBody ModifySysUserDTO dto) {
        if (StringUtils.isEmpty(dto.getOldPwd()) || StringUtils.isEmpty(dto.getNewPwd())) {
            throw new BusinessException("旧密码与新密码不能为空");
        }
        dto.setId(AdminContextManage.getContext().getId());
        userPermissionService.updatePwd(dto);
        return true;
    }

    @PostMapping("/del")
    @ApiOperation(value = "删除用户接口")
    @AdminLogAnnotation(title = "用户管理", action = "删除用户")
    public Object deletedUser(@RequestBody List<Long> userIds) {
        //删除用户， 删除redis的绑定的角色跟权限
        if (userIds.contains(AdminContextManage.getContext().getId())) {
            throw new BusinessException("不能删除自己");
        }
        userSessionService.abortUserByUserIds(userIds);
        userService.lambdaUpdate().in(SysAdmin::getId, userIds).remove();
        sysAdminRoleService.lambdaUpdate().in(SysAdminRole::getUserId, userIds).remove();
        return true;
    }

    @PostMapping("/queryRoles/{userId}")
    @ApiOperation(value = "赋予角色-获取所有角色接口")
    @AdminLogAnnotation(title = "用户管理", action = "赋予角色-获取所有角色接口")
    public Object getUserOwnRole(@PathVariable("userId") Long userId) {
        return userPermissionService.getUserOwnRole(userId);
    }

    @Autowired
    private SysAdminRoleService sysAdminRoleService;

    @PostMapping("/roles/{userId}/{roleId}")
    @ApiOperation(value = "赋予角色-用户赋予角色接口")
    @AdminLogAnnotation(title = "用户管理", action = "赋予角色-用户赋予角色接口")
    public Object setUserOwnRole(@PathVariable("userId") String userId, @PathVariable String roleId) {
        sysAdminRoleService.removeByColumn("user_id", userId);
        if (null != roleId) {
            UserRoleOperationReqVO reqVO = new UserRoleOperationReqVO();
            reqVO.setUserId(userId);
            reqVO.setRoleIds(Arrays.asList(roleId));
            userPermissionService.addUserRoleInfo(reqVO);
        }
        userSessionService.reflashTicket(userId);
        return true;
    }

    /**
     * 校验图像验证码
     *
     * @param imageCode 验证码
     */
    private void validImageCode(String imageCode) {
        String capt = redisTemplate.opsForValue().get("netcom:captcha:" + imageCode);
        if (capt == null || StringUtils.isEmpty(capt) || !capt.equals(imageCode)) {
            throw new BusinessException("验证码输入错误");
        }
        redisTemplate.delete("netcom:captcha:" + imageCode);
    }

}
